<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2022/6/1
 * Time: 11:30
 */

namespace app\middleware;


use app\exception\IndexException;
use app\model\user\UserLoginRecordModel;
use app\model\user\UserModel;
use support\Cache;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;

class JwtToken implements MiddlewareInterface
{
    public function process(Request $request, callable $next): Response
    {
        // 通过反射获取控制器哪些方法不需要登录
        $controller = new \ReflectionClass($request->controller);
        $parentClass = $controller->getParentClass()->getName();
        $isLogin = true;

        if($controller->hasProperty('noLogin')){
            $noLoginMethods = $controller->getProperty('noLogin')->getValue((new $request->controller));
            $noLoginMethods = is_array($noLoginMethods)?$noLoginMethods:[];
            foreach ($noLoginMethods as $action){
                if(strtolower($request->action)==strtolower($action)){
                    $isLogin = false;
                    break;
                }
            }
        }

        if(strpos($parentClass,'BaseController')===false){
            $isLogin = false;
        }

        try{
            $this->getUserInfo($request);
        }catch (IndexException $e){
            if($isLogin==true){
                throw $e;
            }
        }

        return $next($request);
    }

    private function getUserInfo($request)
    {
        $request->token = $request->header('token');

        if(empty($request->token)){
            throw new IndexException(1000,'Token不存在或已失效，请重新登录');
        }

        $count = UserLoginRecordModel::getInstance()->getWhere(['token_md5'=>md5(request()->token),['isdel','>',0]])->count();
        if($count){
            throw new IndexException(1001,'登录失效，手机号已在其他设备登录');
        }

        //检查token是否已经被注销掉了
        $deleteToken = Cache::get('delete_user_'.md5(request()->token));
        if($deleteToken==false){
            $userInfo = \app\common\lib\JwtToken::getInstance()->validateToken($request->token);
        }

        if(empty($userInfo)){
            throw new IndexException(1000,'token error');
        }

        $userInfo = json_decode(json_encode($userInfo), true);
        
        $user = Cache::get(md5($request->token));
        if(!empty($user)){
            $userInfo = $user;
        }elseif((time()-$userInfo['login_time'])>60){
            $userInfo = UserModel::getInstance()->getWhere(['user_sn'=>$userInfo['user_sn'],'isdel'=>0])->first();
            if(empty($userInfo)){
                throw new IndexException(1000,'用户不存在');
            }

            $userInfo = $this->loginData($userInfo);
            $userInfo = $userInfo->toArray();
            Cache::set(md5($request->token),$userInfo,60);
        }

        $userInfo = json_decode(json_encode($userInfo), true);
        $request->curUserId = $userInfo['user_sn'];
        $request->curUserName = $userInfo['nickname'];
        $request->curUserInfo = $userInfo;

        //返回true表示用户已经登录
        return true;
    }

    protected function loginData($user)
    {
        unset($user->userid);

        return $user;
    }

}
